package gui.testSetup;

import common.Constants;
import gui.testSetup.components.TestConfSetting;
import gui.testSetup.components.PageDescriptionViewer;
import gui.testSetup.components.PageInputEditor;
import gui.GUIController;
import gui.projectSetup.ProjectConfigurationWindow;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import testGenerator.Controller;

/**
 * Provides a wizard to build a new test.
 * @author William Whitney
 */
public class NewTestWizard extends JFrame
{

    private static final Dimension k_windowSize = new Dimension(600, 500);
    private final GUIController guiController;
    private final Controller controller;
    private TestConfSetting currPage;
    private JButton finishBtn;
    private JButton cancelBtn;
    private JLabel pageTitle;
    private PageDescriptionViewer pageDescriptionViewer;
    private final PageInputEditor pageInputEditor;

    /**
     * Default constructor.
     * @param guiController gui logic controller
     * @param controller data logic controller
     */
    public NewTestWizard(GUIController guiController, Controller controller) throws FileNotFoundException, IOException
    {
        //Save Controllers
        this.guiController = guiController;
        this.controller = controller;

        //Set Start Page
        currPage = TestConfSetting.CODE_LOCATION;
 
        String sourceCodePath = getSourceCodePath();
        
        //Create dynamically changing objects
        pageDescriptionViewer = new PageDescriptionViewer(currPage.getDescription());
        if("".equals(sourceCodePath)) {
            pageInputEditor = new PageInputEditor(currPage, this.guiController.getLastVisitedDirectory());
        }
        else {
            pageInputEditor = new PageInputEditor(currPage, new File(sourceCodePath));
        }

        
        
        //Configure JFrame Properties
        this.setupFrame();

        //Render View
        this.setContentPane(this.getView());
    }

    /**
     * Makes the new test wizard visible.
     */
    public void showUI()
    {
        this.setVisible(true);
    }

    /**
     * Configures the JFrame properties.
     */
    private void setupFrame()
    {
        //Set size
        this.setPreferredSize(k_windowSize);
        this.setMinimumSize(k_windowSize);

        //Set Title
        this.setTitle("New Test Wizard");

        //Set default close operation
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);


    }

    /**
     * Adds the primary JPanel to the JFrame.
     */
    private JPanel getView()
    {
        JPanel panel = new JPanel();
        //Setup Frame Panel
        BorderLayout layout = new BorderLayout();
        panel = new JPanel();
        panel.setLayout(layout);

        //Get The title
        panel.add(this.getPageTitleBar(), BorderLayout.NORTH);

        //Add Input Editor
        panel.add(this.pageInputEditor, BorderLayout.CENTER);

        //Add forward, back, finished buttons
        panel.add(this.getButtonBar(), BorderLayout.SOUTH);

        return panel;
    }

    /**
     * Returns a JPanel that is the title bar.
     * @return JPanel that has page title and other related info
     */
    public JPanel getPageTitleBar()
    {
        JPanel titlePanel = new JPanel();
        titlePanel.setLayout(new BorderLayout());

        //North
        pageTitle = new JLabel(currPage.getTitle());
        pageTitle.setFont(Constants.getHeadingFont());
        titlePanel.add(pageTitle, BorderLayout.NORTH);

        //Center
        titlePanel.add(pageDescriptionViewer, BorderLayout.CENTER);

        //South
        titlePanel.add(new JLabel("  "), BorderLayout.SOUTH);

        return titlePanel;
    }

    public JPanel getButtonBar()
    {
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());

        //Create Buttons     
        finishBtn = new JButton("Finish");

        cancelBtn = new JButton("Cancel");

        finishBtn.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e)
            {
                if (isValidFile())
                {
                    controller.reset();
                    controller.setTestConf(TestConfSetting.CODE_LOCATION, pageInputEditor.getValue());
                    controller.interpretSource();
                    guiController.updateExecutionPathEditor();
                    guiController.updateFilePath();
                    guiController.showCode();
                    guiController.highlightLine();
                    guiController.setIsBeforeWizardRun(false);
                    guiController.getBasisPathController().render();
                    guiController.saveLastVisitedDirectory(pageInputEditor.getLastVisitedDirectory());

                    dispose();
                }
            }
        });

        cancelBtn.addActionListener(new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e)
            {
                dispose();
            }
        });
        buttonPanel.add(cancelBtn);
        buttonPanel.add(finishBtn);


        return buttonPanel;
    }

    private boolean isValidFile()
    {
        File file = new File(pageInputEditor.getValue());

        if (!file.exists())
        {
            JOptionPane.showMessageDialog(this,
                    "Could Not Find Java Source File.", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return false;
        }
        return true;
    }
    
    private String getSourceCodePath() throws FileNotFoundException, IOException {
        Properties projectConfiguration = new Properties();
        
        
        FileInputStream in = new FileInputStream("appConfig");    
        projectConfiguration.load(in);            
        in.close();
             
        return projectConfiguration.getProperty("SourceCodePath");
    }
}
